Introdução

Análise exploratória de dados do RottenTomatoes sobre o ator Jake Gyllenhaal. O código empregado na extração dos dados aqui analizados e a descrição de como o usar encontra-se no repositório origem deste relatório.

  • Entradas que não contêm dados sobre bilheteria foram ignorados.

Data Overview

import_data("jake_gyllenhaal") 
filmes <- read_imported_data()
filmes %>% 
    glimpse()
Observations: 20
Variables: 5
$ avaliacao  <int> 92, 68, 73, 52, 73, 59, 82, 85, 92, 49, 35, 64, 47, 90, 87, 61, 62, 44, ...
$ filme      <chr> "Stronger", "Life", "Nocturnal Animals", "Demolition", "Everest", "South...
$ papel      <chr> "Jeff Bauman", "David Jordan", "Tony HastingsEdward Sheffield", "Davis M...
$ bilheteria <dbl> 4.2, 30.2, 10.7, 1.7, 46.6, 42.4, 61.0, 39.1, 54.7, 33.3, 90.8, 28.6, 9....
$ ano        <int> 2017, 2017, 2016, 2016, 2015, 2015, 2013, 2012, 2011, 2010, 2010, 2009, ...

Bilheteria

p <- filmes %>%
    ggplot(aes(x = ano, 
               y = bilheteria,
               text = paste("Filme:",filme,
                            "\nBilheteria:",
                            bilheteria,"m",
                            "\nAno:",ano))) + 
    geom_point(size = 4, color = paleta[1]) +
    labs(y = "Bilheteria", x = "Ano de lançamento")
ggplotly(p, tooltip = "text") %>%
    layout(autosize = F)
  • Bilheteria e ano de lançamento
filmes %>% 
    ggplot(aes(x = bilheteria)) + 
    geom_histogram(aes(y=(..count..)/sum(..count..)),binwidth = 10, boundary = 0, 
                   fill = "grey", color = "black") + 
    geom_rug(size = .5) +
    scale_x_continuous(breaks=seq(0,200,20)) +
    labs(y = "Frequência Relativa", x = "Bilheteria")

filmes %>% 
    group_by(filme) %>%
    ggplot(aes(sample=bilheteria)) + 
        stat_qq()

p <- filmes %>% 
    ggplot(aes(x = "",
               y = bilheteria,
               label = filme,
               text = paste("Filme:",filme,
                            "\nBilheteria:",
                            bilheteria,"m"))) + 
    geom_jitter(width = .05, alpha = .3, size = 3) + 
    labs(x = "", y="Bilheteria")
ggplotly(p, tooltip="text") %>% 
    layout(autosize = F)

Avaliação

p <- filmes %>% 
    ggplot(aes(x = ano, 
               y = avaliacao,
                text = paste("Filme:",filme,
                            "\nAvaliação:",
                            avaliacao,
                            "\nAno:",ano))) + 
    geom_point(size = 4, color = paleta[1])  +
    scale_y_continuous(limits = c(0, 100)) +
    labs(y = "Avaliação RT", x = "Ano de lançamento")
ggplotly(p, tooltip = "text") %>%
    layout(autosize = F)
filmes %>% 
    ggplot(aes(x = avaliacao)) + 
    geom_histogram(aes(y=(..count..)/sum(..count..)),binwidth = 10, boundary = 0, 
                   fill = paleta[3], color = "black") + 
    geom_rug(size = .5) +
    scale_x_continuous(breaks=seq(0,100,10)) +
    labs(y = "Frequência Relativa", x = "Avaliação RT")

filmes %>% 
    group_by(filme) %>%
    ggplot(aes(sample=avaliacao)) + 
    stat_qq() 

p <- filmes %>% 
    ggplot(aes(x = "",
               y = avaliacao,
               text = paste(
                    "Filme:",filme,
                    "\nAvaliação:",avaliacao))) + 
    geom_jitter(width = .05, alpha = .3, size = 3) + 
    labs(x = "", y="Avaliação RT")
ggplotly(p, tooltip = "text") %>% 
    layout(autosize = F)

Agrupamento hierárquico

Uma dimensão

agrupamento_h = filmes %>% 
    mutate(nome = paste0(filme, " (av=", avaliacao, ")")) %>% 
    as.data.frame() %>% 
    column_to_rownames("filme") %>% 
    select(avaliacao) %>%
    dist(method = "euclidian") %>% 
    hclust(method = "ward.D")
ggdendrogram(agrupamento_h, rotate = T, size = 2, theme_dendro = F) + 
    labs(y = "Dissimilaridade", x = "", title = "Dendrograma")

get_grupos <- function(agrupamento, num_grupos){
    agrupamento %>% 
        cutree(num_grupos) %>% 
        as.data.frame() %>% 
        mutate(label = rownames(.)) %>% 
        gather(key =  "k", value = "grupo", -label) %>% 
        mutate(grupo = as.character(grupo))
}
atribuicoes = get_grupos(agrupamento_h, num_grupos = 1:6)
atribuicoes = atribuicoes %>% 
    left_join(filmes, by = c("label" = "filme"))
atribuicoes %>% 
    ggplot(aes(x = "Filmes", y = avaliacao, colour = grupo)) + 
    geom_jitter(width = .02, height = 0, size = 1.6, alpha = .6) + 
    facet_wrap(~ paste(k, " grupos")) + 
    scale_color_brewer(palette = "Dark2") +
    labs(y = "Avaliação RT", x = "", title = "Clusterização com uma Dimensão")

k_escolhido = 3
p <-atribuicoes %>% 
    filter(k == k_escolhido) %>% 
    ggplot(aes(x = reorder(label, avaliacao),
               y = avaliacao,
               colour = grupo,
               text = paste(
                    "Filme:", reorder(label, avaliacao),
                    "\nAvaliação:", avaliacao,
                    "\nGrupo:", grupo))) + 
    geom_jitter(width = .02, height = 0, size = 3, alpha = .6) + 
    facet_wrap(~ paste(k, " grupos")) + 
    scale_color_brewer(palette = "Dark2") + 
    labs(x = "", y = "Avaliação RT") + 
    coord_flip()
ggplotly(p,tooltip = "text") %>%
    layout(autosize = F)

Com duas dimensões

agrupamento_h_2d = filmes %>%
   mutate(bilheteria = log10(bilheteria)) %>%
   mutate_at(vars("avaliacao", "bilheteria"), funs(scale)) %>%
   column_to_rownames("filme") %>%
   select("avaliacao", "bilheteria") %>%
   dist(method = "euclidean") %>%
   hclust(method = "ward.D")
Setting row names on a tibble is deprecated.
ggdendrogram(agrupamento_h_2d, rotate = TRUE, theme_dendro = F) +
    labs(y = "Dissimilaridade", x = "", title = "Dendrograma")

filmes2 <- filmes %>%
    mutate(bilheteria = log10(bilheteria))
plota_hclusts_2d(agrupamento_h_2d,
                filmes2,
                c("avaliacao", "bilheteria"),
                linkage_method = "ward.D", 
                ks = 1:6,
                palette = "Dark2") + 
    scale_y_log10() +
    labs(y = "Bilheteria", x = "Avaliação", title = "Clusterização com Duas Dimensões")

atribuicoes = get_grupos(agrupamento_h_2d, num_grupos = 1:6)
atribuicoes = atribuicoes %>% 
    filter(k == 3) %>%
    mutate(filme = label) %>% 
    left_join(filmes, by = "filme")
p <- atribuicoes %>%
    ggplot(aes(x = avaliacao,
               y = bilheteria,
               colour = grupo,
               text = paste(
                    "Filme:", filme,
                    "\nBilheteria:", bilheteria,"m\n",
                    "Avaliação:", avaliacao))) + 
    geom_jitter(width = .02, height = 0, size = 3, alpha = .6) + 
    facet_wrap(~ paste(k, " grupos")) + 
    scale_color_brewer(palette = "Dark2") +
    scale_y_log10() +
    labs(y = "Bilheteria", x = "Avaliação RT")
ggplotly(p, tooltip = "text") %>%
    layout(autosize = F)
LS0tCnRpdGxlOiAiVGlwb3MgZGUgZmlsbWUgZGUgSmFrZSBHeWxsZW5oYWFsIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwotLS0KCiMjIEludHJvZHXDp8OjbwoKPiBBbsOhbGlzZSBleHBsb3JhdMOzcmlhIGRlIGRhZG9zIGRvIFtSb3R0ZW5Ub21hdG9lc10oaHR0cHM6Ly93d3cucm90dGVudG9tYXRvZXMuY29tLykgc29icmUgbyBhdG9yIEpha2UgR3lsbGVuaGFhbC4gTyBjw7NkaWdvIGVtcHJlZ2FkbyBuYSBleHRyYcOnw6NvIGRvcyBkYWRvcyBhcXVpIGFuYWxpemFkb3MgZSBhIGRlc2NyacOnw6NvIGRlIGNvbW8gbyB1c2FyIGVuY29udHJhLXNlIG5vICBbcmVwb3NpdMOzcmlvIG9yaWdlbV0oaHR0cHM6Ly9naXRodWIuY29tL0JlbmFyZGkvYWdydXBhbWVudG8tZmlsbWVzLykgZGVzdGUgcmVsYXTDs3Jpby4KCiogRW50cmFkYXMgcXVlIG7Do28gY29udMOqbSBkYWRvcyBzb2JyZSBiaWxoZXRlcmlhIGZvcmFtIGlnbm9yYWRvcy4KCgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShoZXJlKQpsaWJyYXJ5KGNsdXN0ZXIpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGdnZGVuZHJvKQoKc291cmNlKGhlcmU6OmhlcmUoImNvZGUvbGliLlIiKSkKc291cmNlKGhlcmU6OmhlcmUoImNvZGUvcGxvdGFfc29sdWNvZXNfaGNsdXN0LlIiKSkKCnRoZW1lX3NldCh0aGVtZV9yZXBvcnQoKSkKCmtuaXRyOjpvcHRzX2NodW5rJHNldCh0aWR5ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGggPSA2LAogICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodCA9IDUsCiAgICAgICAgICAgICAgICAgICAgICBlY2hvID0gVFJVRSkKcGFsZXRhID0gYygiIzQwNEU0RCIsCiAgICAgICAgICAgIiM5MkRDRTUiLAogICAgICAgICAgICIjOTM4QkExIiwKICAgICAgICAgICAiIzJEMzE0MiIsCiAgICAgICAgICAgIiNGNDc0M0IiKQpgYGAKCiMjIERhdGEgT3ZlcnZpZXcKCmBgYHtyIHJlYWQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmltcG9ydF9kYXRhKCJqYWtlX2d5bGxlbmhhYWwiKSAKZmlsbWVzIDwtIHJlYWRfaW1wb3J0ZWRfZGF0YSgpCmZpbG1lcyAlPiUgCiAgICBnbGltcHNlKCkKYGBgCgoKCiMjIyBCaWxoZXRlcmlhCgpgYGB7cn0KcCA8LSBmaWxtZXMgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBhbm8sIAogICAgICAgICAgICAgICB5ID0gYmlsaGV0ZXJpYSwKICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJGaWxtZToiLGZpbG1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuQmlsaGV0ZXJpYToiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmlsaGV0ZXJpYSwibSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG5Bbm86Iixhbm8pKSkgKyAKICAgIGdlb21fcG9pbnQoc2l6ZSA9IDQsIGNvbG9yID0gcGFsZXRhWzFdKSArCiAgICBsYWJzKHkgPSAiQmlsaGV0ZXJpYSIsIHggPSAiQW5vIGRlIGxhbsOnYW1lbnRvIikKCmdncGxvdGx5KHAsIHRvb2x0aXAgPSAidGV4dCIpICU+JQogICAgbGF5b3V0KGF1dG9zaXplID0gRikKYGBgCgoqIEJpbGhldGVyaWEgZSBhbm8gZGUgbGFuw6dhbWVudG8gCgoKYGBge3J9CmZpbG1lcyAlPiUgCiAgICBnZ3Bsb3QoYWVzKHggPSBiaWxoZXRlcmlhKSkgKyAKICAgIGdlb21faGlzdG9ncmFtKGFlcyh5PSguLmNvdW50Li4pL3N1bSguLmNvdW50Li4pKSxiaW53aWR0aCA9IDEwLCBib3VuZGFyeSA9IDAsIAogICAgICAgICAgICAgICAgICAgZmlsbCA9ICJncmV5IiwgY29sb3IgPSAiYmxhY2siKSArIAogICAgZ2VvbV9ydWcoc2l6ZSA9IC41KSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLDIwMCwyMCkpICsKICAgIGxhYnMoeSA9ICJGcmVxdcOqbmNpYSBSZWxhdGl2YSIsIHggPSAiQmlsaGV0ZXJpYSIpCgpgYGAKCmBgYHtyfQpmaWxtZXMgJT4lIAogICAgZ3JvdXBfYnkoZmlsbWUpICU+JQogICAgZ2dwbG90KGFlcyhzYW1wbGU9YmlsaGV0ZXJpYSkpICsgCiAgICAgICAgc3RhdF9xcSgpCmBgYAoKYGBge3J9CnAgPC0gZmlsbWVzICU+JSAKICAgIGdncGxvdChhZXMoeCA9ICIiLAogICAgICAgICAgICAgICB5ID0gYmlsaGV0ZXJpYSwKICAgICAgICAgICAgICAgbGFiZWwgPSBmaWxtZSwKICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJGaWxtZToiLGZpbG1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuQmlsaGV0ZXJpYToiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmlsaGV0ZXJpYSwibSIpKSkgKyAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjA1LCBhbHBoYSA9IC4zLCBzaXplID0gMykgKyAKICAgIGxhYnMoeCA9ICIiLCB5PSJCaWxoZXRlcmlhIikKCmdncGxvdGx5KHAsIHRvb2x0aXA9InRleHQiKSAlPiUgCiAgICBsYXlvdXQoYXV0b3NpemUgPSBGKQpgYGAKCiMjIyBBdmFsaWHDp8OjbwoKYGBge3J9CnAgPC0gZmlsbWVzICU+JSAKICAgIGdncGxvdChhZXMoeCA9IGFubywgCiAgICAgICAgICAgICAgIHkgPSBhdmFsaWFjYW8sCiAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoIkZpbG1lOiIsZmlsbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXG5BdmFsaWHDp8OjbzoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhbGlhY2FvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlxuQW5vOiIsYW5vKSkpICsgCiAgICBnZW9tX3BvaW50KHNpemUgPSA0LCBjb2xvciA9IHBhbGV0YVsxXSkgICsKICAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDEwMCkpICsKICAgIGxhYnMoeSA9ICJBdmFsaWHDp8OjbyBSVCIsIHggPSAiQW5vIGRlIGxhbsOnYW1lbnRvIikKCmdncGxvdGx5KHAsIHRvb2x0aXAgPSAidGV4dCIpICU+JQogICAgbGF5b3V0KGF1dG9zaXplID0gRikKYGBgCgpgYGB7cn0KZmlsbWVzICU+JSAKICAgIGdncGxvdChhZXMoeCA9IGF2YWxpYWNhbykpICsgCiAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeT0oLi5jb3VudC4uKS9zdW0oLi5jb3VudC4uKSksYmlud2lkdGggPSAxMCwgYm91bmRhcnkgPSAwLCAKICAgICAgICAgICAgICAgICAgIGZpbGwgPSBwYWxldGFbM10sIGNvbG9yID0gImJsYWNrIikgKyAKICAgIGdlb21fcnVnKHNpemUgPSAuNSkgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1zZXEoMCwxMDAsMTApKSArCiAgICBsYWJzKHkgPSAiRnJlcXXDqm5jaWEgUmVsYXRpdmEiLCB4ID0gIkF2YWxpYcOnw6NvIFJUIikKCmBgYAoKYGBge3J9CmZpbG1lcyAlPiUgCiAgICBncm91cF9ieShmaWxtZSkgJT4lCiAgICBnZ3Bsb3QoYWVzKHNhbXBsZT1hdmFsaWFjYW8pKSArIAogICAgc3RhdF9xcSgpIApgYGAKCmBgYHtyfQpwIDwtIGZpbG1lcyAlPiUgCiAgICBnZ3Bsb3QoYWVzKHggPSAiIiwKICAgICAgICAgICAgICAgeSA9IGF2YWxpYWNhbywKICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKAogICAgICAgICAgICAgICAgICAgICJGaWxtZToiLGZpbG1lLAogICAgICAgICAgICAgICAgICAgICJcbkF2YWxpYcOnw6NvOiIsYXZhbGlhY2FvKSkpICsgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4wNSwgYWxwaGEgPSAuMywgc2l6ZSA9IDMpICsgCiAgICBsYWJzKHggPSAiIiwgeT0iQXZhbGlhw6fDo28gUlQiKQoKZ2dwbG90bHkocCwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lIAogICAgbGF5b3V0KGF1dG9zaXplID0gRikKCmBgYAoKIyMgQWdydXBhbWVudG8gaGllcsOhcnF1aWNvCgojIyMgVW1hIGRpbWVuc8OjbwoKYGBge3J9CmFncnVwYW1lbnRvX2ggPSBmaWxtZXMgJT4lIAogICAgbXV0YXRlKG5vbWUgPSBwYXN0ZTAoZmlsbWUsICIgKGF2PSIsIGF2YWxpYWNhbywgIikiKSkgJT4lIAogICAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICAgIGNvbHVtbl90b19yb3duYW1lcygiZmlsbWUiKSAlPiUgCiAgICBzZWxlY3QoYXZhbGlhY2FvKSAlPiUKICAgIGRpc3QobWV0aG9kID0gImV1Y2xpZGlhbiIpICU+JSAKICAgIGhjbHVzdChtZXRob2QgPSAid2FyZC5EIikKCmdnZGVuZHJvZ3JhbShhZ3J1cGFtZW50b19oLCByb3RhdGUgPSBULCBzaXplID0gMiwgdGhlbWVfZGVuZHJvID0gRikgKyAKICAgIGxhYnMoeSA9ICJEaXNzaW1pbGFyaWRhZGUiLCB4ID0gIiIsIHRpdGxlID0gIkRlbmRyb2dyYW1hIikKYGBgCgpgYGB7cn0KZ2V0X2dydXBvcyA8LSBmdW5jdGlvbihhZ3J1cGFtZW50bywgbnVtX2dydXBvcyl7CiAgICBhZ3J1cGFtZW50byAlPiUgCiAgICAgICAgY3V0cmVlKG51bV9ncnVwb3MpICU+JSAKICAgICAgICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogICAgICAgIG11dGF0ZShsYWJlbCA9IHJvd25hbWVzKC4pKSAlPiUgCiAgICAgICAgZ2F0aGVyKGtleSA9ICAiayIsIHZhbHVlID0gImdydXBvIiwgLWxhYmVsKSAlPiUgCiAgICAgICAgbXV0YXRlKGdydXBvID0gYXMuY2hhcmFjdGVyKGdydXBvKSkKfQoKYXRyaWJ1aWNvZXMgPSBnZXRfZ3J1cG9zKGFncnVwYW1lbnRvX2gsIG51bV9ncnVwb3MgPSAxOjYpCgphdHJpYnVpY29lcyA9IGF0cmlidWljb2VzICU+JSAKICAgIGxlZnRfam9pbihmaWxtZXMsIGJ5ID0gYygibGFiZWwiID0gImZpbG1lIikpCgphdHJpYnVpY29lcyAlPiUgCiAgICBnZ3Bsb3QoYWVzKHggPSAiRmlsbWVzIiwgeSA9IGF2YWxpYWNhbywgY29sb3VyID0gZ3J1cG8pKSArIAogICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMDIsIGhlaWdodCA9IDAsIHNpemUgPSAxLjYsIGFscGhhID0gLjYpICsgCiAgICBmYWNldF93cmFwKH4gcGFzdGUoaywgIiBncnVwb3MiKSkgKyAKICAgIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogICAgbGFicyh5ID0gIkF2YWxpYcOnw6NvIFJUIiwgeCA9ICIiLCB0aXRsZSA9ICJDbHVzdGVyaXphw6fDo28gY29tIHVtYSBEaW1lbnPDo28iKQoKYGBgCgpgYGB7cn0Ka19lc2NvbGhpZG8gPSAzCgpwIDwtYXRyaWJ1aWNvZXMgJT4lIAogICAgZmlsdGVyKGsgPT0ga19lc2NvbGhpZG8pICU+JSAKICAgIGdncGxvdChhZXMoeCA9IHJlb3JkZXIobGFiZWwsIGF2YWxpYWNhbyksCiAgICAgICAgICAgICAgIHkgPSBhdmFsaWFjYW8sCiAgICAgICAgICAgICAgIGNvbG91ciA9IGdydXBvLAogICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoCiAgICAgICAgICAgICAgICAgICAgIkZpbG1lOiIsIHJlb3JkZXIobGFiZWwsIGF2YWxpYWNhbyksCiAgICAgICAgICAgICAgICAgICAgIlxuQXZhbGlhw6fDo286IiwgYXZhbGlhY2FvLAogICAgICAgICAgICAgICAgICAgICJcbkdydXBvOiIsIGdydXBvKSkpICsgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4wMiwgaGVpZ2h0ID0gMCwgc2l6ZSA9IDMsIGFscGhhID0gLjYpICsgCiAgICBmYWNldF93cmFwKH4gcGFzdGUoaywgIiBncnVwb3MiKSkgKyAKICAgIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKyAKICAgIGxhYnMoeCA9ICIiLCB5ID0gIkF2YWxpYcOnw6NvIFJUIikgKyAKICAgIGNvb3JkX2ZsaXAoKQoKZ2dwbG90bHkocCx0b29sdGlwID0gInRleHQiKSAlPiUKICAgIGxheW91dChhdXRvc2l6ZSA9IEYpCgpgYGAKCiMjIyBDb20gZHVhcyBkaW1lbnPDtWVzCgpgYGB7cn0KYWdydXBhbWVudG9faF8yZCA9IGZpbG1lcyAlPiUKICAgbXV0YXRlKGJpbGhldGVyaWEgPSBsb2cxMChiaWxoZXRlcmlhKSkgJT4lCiAgIG11dGF0ZV9hdCh2YXJzKCJhdmFsaWFjYW8iLCAiYmlsaGV0ZXJpYSIpLCBmdW5zKHNjYWxlKSkgJT4lCiAgIGNvbHVtbl90b19yb3duYW1lcygiZmlsbWUiKSAlPiUKICAgc2VsZWN0KCJhdmFsaWFjYW8iLCAiYmlsaGV0ZXJpYSIpICU+JQogICBkaXN0KG1ldGhvZCA9ICJldWNsaWRlYW4iKSAlPiUKICAgaGNsdXN0KG1ldGhvZCA9ICJ3YXJkLkQiKQoKZ2dkZW5kcm9ncmFtKGFncnVwYW1lbnRvX2hfMmQsIHJvdGF0ZSA9IFRSVUUsIHRoZW1lX2RlbmRybyA9IEYpICsKICAgIGxhYnMoeSA9ICJEaXNzaW1pbGFyaWRhZGUiLCB4ID0gIiIsIHRpdGxlID0gIkRlbmRyb2dyYW1hIikKYGBgCgpgYGB7cn0KZmlsbWVzMiA8LSBmaWxtZXMgJT4lCiAgICBtdXRhdGUoYmlsaGV0ZXJpYSA9IGxvZzEwKGJpbGhldGVyaWEpKQoKcGxvdGFfaGNsdXN0c18yZChhZ3J1cGFtZW50b19oXzJkLAogICAgICAgICAgICAgICAgZmlsbWVzMiwKICAgICAgICAgICAgICAgIGMoImF2YWxpYWNhbyIsICJiaWxoZXRlcmlhIiksCiAgICAgICAgICAgICAgICBsaW5rYWdlX21ldGhvZCA9ICJ3YXJkLkQiLCAKICAgICAgICAgICAgICAgIGtzID0gMTo2LAogICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJEYXJrMiIpICsgCiAgICBzY2FsZV95X2xvZzEwKCkgKwogICAgbGFicyh5ID0gIkJpbGhldGVyaWEiLCB4ID0gIkF2YWxpYcOnw6NvIiwgdGl0bGUgPSAiQ2x1c3Rlcml6YcOnw6NvIGNvbSBEdWFzIERpbWVuc8O1ZXMiKQpgYGAKCmBgYHtyfQphdHJpYnVpY29lcyA9IGdldF9ncnVwb3MoYWdydXBhbWVudG9faF8yZCwgbnVtX2dydXBvcyA9IDE6NikKCmF0cmlidWljb2VzID0gYXRyaWJ1aWNvZXMgJT4lIAogICAgZmlsdGVyKGsgPT0gMykgJT4lCiAgICBtdXRhdGUoZmlsbWUgPSBsYWJlbCkgJT4lIAogICAgbGVmdF9qb2luKGZpbG1lcywgYnkgPSAiZmlsbWUiKQoKcCA8LSBhdHJpYnVpY29lcyAlPiUKICAgIGdncGxvdChhZXMoeCA9IGF2YWxpYWNhbywKICAgICAgICAgICAgICAgeSA9IGJpbGhldGVyaWEsCiAgICAgICAgICAgICAgIGNvbG91ciA9IGdydXBvLAogICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoCiAgICAgICAgICAgICAgICAgICAgIkZpbG1lOiIsIGZpbG1lLAogICAgICAgICAgICAgICAgICAgICJcbkJpbGhldGVyaWE6IiwgYmlsaGV0ZXJpYSwibVxuIiwKICAgICAgICAgICAgICAgICAgICAiQXZhbGlhw6fDo286IiwgYXZhbGlhY2FvKSkpICsgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4wMiwgaGVpZ2h0ID0gMCwgc2l6ZSA9IDMsIGFscGhhID0gLjYpICsgCiAgICBmYWNldF93cmFwKH4gcGFzdGUoaywgIiBncnVwb3MiKSkgKyAKICAgIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKwogICAgc2NhbGVfeV9sb2cxMCgpICsKICAgIGxhYnMoeSA9ICJCaWxoZXRlcmlhIiwgeCA9ICJBdmFsaWHDp8OjbyBSVCIpCgoKZ2dwbG90bHkocCwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lCiAgICBsYXlvdXQoYXV0b3NpemUgPSBGKQpgYGAK